#include "ce_core.h"

void
ce_lock_init(ce_lock_t *lock) {
    pthread_mutex_init(&lock->lock, NULL);
}

void
ce_lock_destroy(ce_lock_t *lock) {
    pthread_mutex_destroy(&lock->lock);
}

void
ce_lock_lock(ce_lock_t *lock) {
    pthread_mutex_lock(&lock->lock);
}

void
ce_lock_unlock(ce_lock_t *lock) {
    pthread_mutex_unlock(&lock->lock);
}


void
ce_rwlock_init(ce_rwlock_t *lock) {
    pthread_rwlock_init(&lock->lock, NULL);
}

void
ce_rwlock_destroy(ce_rwlock_t *lock) {
    pthread_rwlock_destroy(&lock->lock);
}

void
ce_rwlock_wlock(ce_rwlock_t *lock) {
    pthread_rwlock_wrlock(&lock->lock);
}

void
ce_rwlock_wunlock(ce_rwlock_t *lock) {
    pthread_rwlock_unlock(&lock->lock);
}

void
ce_rwlock_rlock(ce_rwlock_t *lock) {
    pthread_rwlock_rdlock(&lock->lock);
}

void
ce_rwlock_runlock(ce_rwlock_t *lock) {
    pthread_rwlock_unlock(&lock->lock);
}


#define spin 2048

void
ce_spinlock_init(ce_spinlock_t *lock) {
    *lock = 0;
}

void
ce_spinlock_destroy(ce_spinlock_t *lock) {
}

void
ce_spinlock_lock(ce_spinlock_t *lock) {
    for (;;) {
        if (ce_atomic_cmp_set(lock, 0, 1)) {
            return;
        }

        for (int n = 1; n < spin; n <<= 1) {
            for (int i = 0; i < n; i++) {
                ce_cpu_pause();
            }

            if (ce_atomic_cmp_set(lock, 0, 1)) {
                return;
            }
        }

        ce_cpu_yield();
    }
}

void
ce_spinlock_unlock(ce_spinlock_t *lock) {
    *lock = 0;
}
